﻿using AutoMapper;
using ManagementApi.Authorizers;
using ManagementApi.Models;
using ManagementApi.Models.Person;
using ManagementApi.Mvc;
using ManagementApi.Mvc.ApplicationContexts;
using ManagementApi.Mvc.Filters;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Modules;
using Modules.Attachment;
using Modules.Corp;
using Modules.Person;
using Modules.Project;
using Pipelines.Sockets.Unofficial.Arenas;
using PmSoft.Exceptions;
using PmSoft.Utilities;
using static Modules.Person.PersonConstants;

namespace ManagementApi.Controllers.CommanderPannel
{
    /// <summary>
    /// 指挥部-人员合同接口
    /// </summary>
    [Route("/api/v1/commander/contract")]
    [ApiController]
    [Authorize(Roles = "Commander")]
    [TypeFilter(typeof(RequireSelProjectActionFilter))]
    public class PersonContractController : ControllerBase
    {
        private readonly PersonCorpContractService personCorpContractService;
        private readonly PersonAttachmentService personAttachmentService;
        private readonly PersonService personService;
        private readonly CorpService corpService;
        private readonly ProjectCommanderApplicationContext applicationContext;
        private readonly IMapper mapper;
        private readonly ProjectGroupMemberService projectGroupMemberService;
        private readonly PersonContractOwnAuthorizer ownAuthorizer;

        public PersonContractController(PersonCorpContractService personCorpContractService, CorpService corpService, PersonAttachmentService personAttachmentService, PersonService personService, ProjectCommanderApplicationContext applicationContext, IMapper mapper, ProjectGroupMemberService projectGroupMemberService, PersonContractOwnAuthorizer ownAuthorizer)
        {
            this.personCorpContractService = personCorpContractService;
            this.personAttachmentService = personAttachmentService;
            this.personService = personService;
            this.corpService = corpService;
            this.mapper = mapper;
            this.applicationContext = applicationContext;
            this.projectGroupMemberService = projectGroupMemberService;
            this.ownAuthorizer = ownAuthorizer;
        }

        /// <summary>
        /// 新增合同接口
        /// </summary>
        /// <param name="form"></param>
        [HttpPost("create")]
        public ApiResult CreateContract(PersonContractForm form)
        {
            PersonCorpContract entity = new PersonCorpContract();
            mapper.Map(form, entity);
            entity.ProjectId = applicationContext.CurrentProjectInfo.ProjectId;
            personCorpContractService.Create(entity, form.Attachments.Select(a => a.AttachmentId));
            return ApiResult.Success("新增成功");
        }

        /// <summary>
        /// 修改合同
        /// </summary>
        /// <param name="id"></param>
        /// <param name="form"></param>
        /// <returns></returns>
        [HttpPut("update/{id}")]
        public ApiResult CreateContract(int id, PersonContractForm form)
        {
            PersonCorpContract? personCorpContract = personCorpContractService.GetPersonCorpContract(id);
            if (personCorpContract == null)
                return ApiResult.Failure("合同信息不存在");

            #region 验证数据权限

            ownAuthorizer.CheckAndThrowIfOwnAuthenticationFailed(id);

            #endregion 验证数据权限

            personCorpContractService.Update(mapper.Map(form, personCorpContract), form.Attachments.Select(a => a.AttachmentId));
            return ApiResult.Success("修改成功");
        }

        /// <summary>
        /// 获取合同详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet("{id}")]
        public ApiResult<PersonContractForm> Get(int id)
        {
            PersonCorpContract? personCorpContract = personCorpContractService.GetPersonCorpContract(id);
            if (personCorpContract == null)
                return ApiResult<PersonContractForm>.Failure("合同信息不存在");
            PersonContractForm personContractForm = new PersonContractForm();
            mapper.Map(personCorpContract, personContractForm);
            personContractForm.CorpName = corpService.GetCorpInfo(personCorpContract.CorpId)?.Name;
            PersonInfo? personInfo = personService.GetPerson(personCorpContract.PersonId);
            if (personInfo == null) return ApiResult<PersonContractForm>.Failure("人员信息不存在");
            personContractForm.PersonName = personInfo.Name;
            personContractForm.PersonCardNumber = personInfo.CardNumber;

            #region 附件查询

            var attachments = personAttachmentService.GetSysAttachmentByObjectIdAndType(personCorpContract.Id, 人员附件类型.合同附件, 人员附件租户.Contract);
            List<AttachmentsForm<int>> attach = new();
            foreach (var item in attachments)
            {
                AttachmentsForm<int> attachmentsForm = new()
                {
                    AttachmentId = item.Id,
                    AttachmentName = item.FriendlyName,
                };
                attach.Add(attachmentsForm);
            }
            personContractForm.Attachments = attach;

            #endregion 附件查询

            return ApiResult<PersonContractForm>.Success(personContractForm);
        }

        /// <summary>
        /// 合同信息分页
        /// </summary>
        /// <param name="query"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        [HttpGet("page")]
        public ApiResult<PageDto<PersonContractDto>> GetPages([FromQuery] PersonCorpContractQuery query, int pageIndex = 1, int pageSize = 20)
        {
            query.ProjectId = applicationContext.CurrentProjectInfo.ProjectId;
            var pages = personCorpContractService.GetPersonCorpContracts(query, pageIndex, pageSize);
            return ApiResult<PageDto<PersonContractDto>>.Success(pages.AsPageDto(m => m.AsDto()));
        }

        /// <summary>
        /// 获取人员合同信息分页
        /// </summary>
        /// <param name="memberId"></param>
        /// <returns></returns>
        [HttpGet("page_member")]
        public ApiResult<IEnumerable<PersonContractDto>> GetPagesByPersonId(int memberId)
        {
            var data = projectGroupMemberService.GetMember(memberId);

            if (data == null)
                return ApiResult<IEnumerable<PersonContractDto>>.Failure("成员信息不存在");
            var list = personCorpContractService.GetPersonCorpContractssByProjectIdAndCorpIdPersonId(data.ProjectId, data.CorpId, data.PersonId);

            return ApiResult<IEnumerable<PersonContractDto>>.Success(list.AsDtos());
        }

        ///// <summary>
        ///// 删除合同信息
        ///// </summary>
        ///// <param name="ids"></param>
        ///// <returns></returns>
        //[HttpDelete("{ids}")]
        //public ApiResult Delete(string ids)
        //{
        //    #region 验证数据权限

        //    ownAuthorizer.CheckAndThrowIfOwnAuthenticationFailed(ValueUtility.ConvertToList<int>(ids));

        //    #endregion 验证数据权限

        //    personCorpContractService.Deleted(ValueUtility.ConvertToList<int>(ids));
        //    return ApiResult.Success("删除成功");
        //}

        /// <summary>
        /// 根据项目id+企业id+人员id 获取合同列表详情
        /// </summary>
        /// <param name="projectId"></param>
        /// <param name="corpId"></param>
        /// <param name="personId"></param>
        /// <returns></returns>
        [HttpGet("getContractsByProjectAndCorpIdAndPersonId/{projectId}/{corpId}")]
        public ApiResult<IEnumerable<PersonContractDto>> GetContracts(int projectId, int corpId, int personId)
        {
            PersonInfo? personInfo = personService.GetPerson(personId);
            if (personInfo == null) return ApiResult<IEnumerable<PersonContractDto>>.Failure("人员信息不存在");
            var data = personCorpContractService.GetPersonCorpContractssByProjectIdAndCorpIdPersonId(projectId, corpId, personId);
            var dtos = data.AsDtos();

            #region 附件查询

            foreach (var item in dtos)
            {
                var attachments = personAttachmentService.GetSysAttachmentByObjectIdAndType(item.Id, 人员附件类型.合同附件, 人员附件租户.Contract);
                List<AttachmentsForm<int>> attach = new();
                foreach (var co in attachments)
                {
                    AttachmentsForm<int> attachmentsForm = new()
                    {
                        AttachmentId = co.Id,
                        AttachmentName = co.FriendlyName,
                    };
                    attach.Add(attachmentsForm);
                }
                item.Attachments = attach;
            }

            #endregion 附件查询

            return ApiResult<IEnumerable<PersonContractDto>>.Success(dtos);
        }
    }
}